跳到主要内容

JZ48 不用加减乘除做加法

https://www.nowcoder.com/practice/59ac416b4b944300b617d4f7f111b215

补充知识:^:就是比较当前位置是否相同,相同返回 0,不相同返回 1

A = 0011 1100
B = 0000 1101

-----------------
A & B = 0000 1100
A | B = 0011 1101
A ^ B = 0011 0001
~A = 1100 0011

1、两个数异或:相当于每一位相加,而不考虑进位; 2、两个数相与,并左移一位:相当于求得进位; 3、将上述两步的结果相加

所以:

public int Add(int num1,int num2) {
while( num2 != 0 ) {
int sum = num1 ^ num2; // 取得相加各位的值
int carray = (num1 & num2) << 1; // 取得进位的值
num1 = sum;
num2 = carray;
}
return num1;
}

原理:

首先看十进制是如何做的: 5+7=12,三步走

第一步:相加各位的值,不算进位,得到 2。 第二步:计算进位值,得到 10。 如果这一步的进位值为 0,那么第一步得到的值就是最终结果。 第三步:重复上述两步,只是相加的值变成上述两步的得到的结果 2 和 10,得到 12。

同样我们可以用三步走的方式计算二进制值相加: 5-101,7-111

第一步:相加各位的值,不算进位,得到 010。(二进制每位相加就相当于各位做异或操作,101 ^ 111) 第二步:计算进位值,得到 1010。(相当于各位做与操作得到 101,再向左移一位得到 1010,(101 & 111) << 1) 第三步:重复上述两步, 各位相加 010^1010=1000,进位值为 100 = (010 & 1010) << 1。 继续重复上述两步:1000^100 = 1100,进位值为 0,跳出循环,1100 为最终结果。